using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;

namespace Pixysoft.BarCode
{
    public class ImageBarCoder
    {
        private int imgHeight = 20;
        private int labelHeight = 9;
        private Font labelFont = new Font("Microsoft Sans Serif", 7);

        private static ImageBarCoder instance;
        public static ImageBarCoder Instance
        {
            get
            {
                lock (typeof(ImageBarCoder))
                {
                    if (instance == null)
                        instance = new ImageBarCoder();
                    return instance;
                }
            }
        }


        public Image GetBarCodeImage(BarCodeType type, string value)
        {
            return GetBarCodeImage(type, value, 1);
        }

        public Image GetBarCodeImage(BarCodeType type, string value, int times)
        {
            string barcode = BarCoder.Instance.GetBarCode(type, value);

            return BarCodeToImage(barcode, times);
        }

        public Image GetBarCodeLabelImage(BarCodeType type, string value)
        {
            return GetBarCodeLabelImage(type, value, 1);
        }

        public Image GetBarCodeLabelImage(BarCodeType type, string value, int times)
        {
            return BarCodeToLabelImage(
                BarCodeToImage(
                BarCoder.Instance.GetBarCode(type, value), times), value);
        }

        private Image BarCodeToImage(string barcode, int times)
        {
            if (barcode == "")
                throw new Exception("EGENERATE_IMAGE-1: Must be encoded first.");

            Bitmap bmp = null;

            //bmp = new Bitmap(barcode.Length * 2, imgHeight);

            bmp = new Bitmap(barcode.Length * times, imgHeight);

            int posX = 0;

            Color barcodeColor = Color.Black;

            posX = 0;

            int barcodeIndex = 0;

            using (Graphics graphics = Graphics.FromImage(bmp))
            {
                while (posX < bmp.Width)
                {

                    if (barcodeIndex < barcode.Length)
                    {
                        if (barcode[barcodeIndex] == '1')
                            barcodeColor = Color.Black;

                        if (barcode[barcodeIndex] == '0')
                            barcodeColor = Color.White;
                    }


                    //lines are 2px wide so draw the appropriate color line vertically

                    //graphics.DrawLine(new Pen(barcodeColor, (float)2), new Point(posX, 0), new Point(posX, bmp.Height));

                    graphics.DrawLine(new Pen(barcodeColor, (float)times), new Point(posX, 0), new Point(posX, bmp.Height));

                    posX += times;

                    barcodeIndex++;
                }
            }


            return bmp;
        }

        private Image BarCodeToLabelImage(Image img, string text)
        {
            using (Graphics graphics = Graphics.FromImage(img))
            {
                graphics.DrawImage(img, (float)0, (float)0);

                graphics.SmoothingMode = SmoothingMode.HighQuality;

                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;

                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                graphics.CompositingQuality = CompositingQuality.HighQuality;

                //color a white box at the bottom of the EncodedValue to hold the string of data

                graphics.FillRectangle(new SolidBrush(Color.White), new Rectangle(0, img.Height - labelHeight, img.Width, labelHeight));

                //draw datastring under the EncodedValue image

                StringFormat format = new StringFormat();

                format.Alignment = StringAlignment.Center;

                graphics.DrawString(text, labelFont, new SolidBrush(Color.Black), (float)(img.Width / 2), img.Height - labelHeight - 2, format);

                graphics.Save();
            }

            return img;
        }

        public int ImgHeight
        {
            get { return imgHeight; }
            set { imgHeight = value; }
        }

        public Font LabelFont
        {
            get
            {
                return labelFont;
            }
            set
            {
                labelFont = value;
            }
        }
    }
}
